﻿using System;
using System.Collections.Generic;
using Common;

namespace Actors.Actions
{
    public delegate bool ActionExecutor<in T>(T action);
    public abstract class Action 
    {
        protected IActionExecutor m_Executor;
        public virtual void Initialize(IActionExecutor executor)
        {
            m_Executor = executor;
        }

        public void Execute()
        {
            bool executeSuccess = false;
            if (m_Executor != null)
            {
                executeSuccess = m_Executor.ExecuteAction(this);
            }

            if (executeSuccess)
            {
                // 在此处理通用部分。 如将命令序列化用于网络传输。

            }
            ReturnAction(this);
        }

        public abstract byte[] Serialize();

        public abstract void Deserialize(byte[] data);

        #region Action Pool
        
        private static readonly Dictionary<Type, Pool<Action>> s_ActionPools = new Dictionary<Type, Pool<Action>>();
        
        public static T GetAction<T>(IActionExecutor executor = null) where T : Action, new()
        {
            var type = typeof(T);
            if (!s_ActionPools.TryGetValue(type, out var pool))
            {
                pool = new Pool<Action>( () => new T(), null);
                s_ActionPools.Add(typeof(T), pool);
            }
            var action = pool.Get() as T;
            action?.Initialize(executor);
            return action;
        }
        
        public static void ReturnAction<T>(T action) where T : Action
        {
            var type = typeof(T);
            if (!s_ActionPools.ContainsKey(type))
            {
                return;
            }
            s_ActionPools[type].Return(action);
        }

        public static int GetPoolSize<T>() where T : Action
        {
            var type = typeof(T);
            if (!s_ActionPools.TryGetValue(type, out var pool))
            {
                return 0;
            }
            return pool.Count;
        }

        #endregion
    }
    
    public class Act_Idle : Action
    {
        public override byte[] Serialize()
        {
            throw new System.NotImplementedException();
        }

        public override void Deserialize(byte[] data)
        {
            throw new System.NotImplementedException();
        }
    }
    
    public class Act_Move : Action
    {
        public UnityEngine.Vector2 MovementInput;
        public override byte[] Serialize()
        {
            throw new System.NotImplementedException();
        }

        public override void Deserialize(byte[] data)
        {
            throw new System.NotImplementedException();
        }
    }
    
    public class Act_Jump : Action
    {
        public override byte[] Serialize()
        {
            throw new System.NotImplementedException();
        }

        public override void Deserialize(byte[] data)
        {
            throw new System.NotImplementedException();
        }
    }
    
    public class Act_Fall : Action
    {
        public override byte[] Serialize()
        {
            throw new System.NotImplementedException();
        }

        public override void Deserialize(byte[] data)
        {
            throw new System.NotImplementedException();
        }
    }

    public class Act_Land : Action
    {
        public override byte[] Serialize()
        {
            throw new System.NotImplementedException();
        }

        public override void Deserialize(byte[] data)
        {
            throw new System.NotImplementedException();
        }
    }
}